#!/usr/bin/env node --harmony
'use strict'
// enhance common error messages
const { enhanceErrorMessages, getVersions, chalk } = require('./packages/cli-shared-utils')

// process.env.NODE_PATH = __dirname + '/../node_modules/'
const program = require('commander')
program
  .version(`qdp-cli ${getVersions().current}`)
  .usage('<command> [options]')

program
  .command('create <app-name>')
  .description('create a new project')
  .alias('c')
  .option('-t, --template <template-name>', '[unused]choose a project template [vue]')
  .option('-c, --config', 'generator config.json')
  .action((name, cmd) => {
    require('./packages/create')(name, cleanArgs(cmd))
  })

program
  .command('generator')
  .description(' generate code from configFile ')
  .alias('g')
  .option('-t, --template <template-name>', '[unused]choose a project template [iview],[iview,lzb]')
  .option('-c, --config <configFile>', 'configfile path [../misc/config.json]')
  .option('-s, --savePath <savePath>', 'target savepath [./src]')
  .option('-m, --module <moduleName>', 'config module name[config.json]')
  .action(cmd => require('./packages/generator')(cleanArgs(cmd)))

program
  .command('ui')
  .description('start and open the qdp-cli ui')
  .option('-p, --port <port>', 'Port used for the UI server (by default search for available port)')
  .option('-D, --dev', 'Run in dev mode')
  .action(cmd => {
    require('./packages/cli-ui')(cleanArgs(cmd))
  })

program
  .command('config')
  .description(' generate config from ymate-model ')
  .action(cmd => require('./packages/generator-config')(cleanArgs(cmd)))

program
  .command('ymate')
  .description(' generate ymate-mvc controller from ymate-model ')
  .option('-c, --controller', 'only generate ymate-mvc controller')
  .action(cmd => require('./packages/generator-ymate')(cleanArgs(cmd)))

// add some useful info on help
program.on('--help', () => {
  console.log()
  console.log(`  Run ${chalk.cyan(`qdp <command> --help`)} for detailed usage of given command.`)
  console.log()
})

program.commands.forEach(c => c.on('--help', () => console.log()))

enhanceErrorMessages('missingArgument', p => `Missing required argument ${chalk.yellow(`<${p}>`)}.`)
enhanceErrorMessages('unknownOption', p => `Unknown option ${chalk.yellow(p)}.`)
enhanceErrorMessages('optionMissingArgument', (option, flag) => `Missing required argument for option ${chalk.yellow(option.flags)}` + (flag ? `, got ${chalk.yellow(flag)}` : ``))

program.parse(process.argv)

function camelize(str) {
  return str.replace(/-(\w)/g, (_, c) => c ? c.toUpperCase() : '')
}

function cleanArgs(cmd) {
  const args = {}
  cmd.options.forEach(o => {
    const key = camelize(o.long.replace(/^--/, ''))
    // if an option is not present and Command has a method with the same name
    // it should not be copied
    if (typeof cmd[key] !== 'function' && typeof cmd[key] !== 'undefined') {
      args[key] = cmd[key]
    }
  })
  args.cwd = process.cwd();
  return args
}
